/*
 * Copyright (c) 2009, Servoy-stuff
 * 
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 * 
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
 * http://www.fsf.org/licensing/licenses/lgpl.txt
 */
package net.stuff.servoy.beans.slider.wicket;

import java.util.Hashtable;

import net.stuff.servoy.beans.slider.IServoySliderBean;
import net.stuff.servoy.beans.slider.ServoyUtils;

import org.apache.wicket.Component;
import org.apache.wicket.ResourceReference;
import org.apache.wicket.Response;
import org.apache.wicket.behavior.AbstractBehavior;
import org.apache.wicket.markup.html.IHeaderResponse;
import org.apache.wicket.markup.html.resources.CompressedResourceReference;
import org.apache.wicket.markup.html.resources.JavascriptResourceReference;
import org.apache.wicket.util.string.CssUtils;
import org.apache.wicket.util.string.JavascriptUtils;

import com.servoy.j2db.util.Debug;
import com.servoy.j2db.util.Utils;

/**
 * @author Servoy Stuff
 * http://www.servoy-stuff.net/
 */
public class SliderScriptingBehavior extends AbstractBehavior {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	private static final String STYLE_TYPE = "styleType";
	private static final String ORIENTATION = "orientation";
	private static final String ENABLED = "enabled";
	private static final String MAXIMUM = "maximumValue";
	private static final String MINIMUM = "minimumValue";
	private static final String MAJOR_TICKS = "majorTicks";
	private static final String MINOR_TICKS = "minorTicks";
	private static final String PRECISION = "precision";
	private static final String INVERTED = "inverted";
	private static final String PAINT_TICKS = "paintTicks";
	private static final String PAINT_LABELS = "paintLabels";
	private static final String PAINT_TRACK = "paintTrack";
	private static final String SNAP_TO_TICKS = "snapToTicks";
	private static final String USING_DECIMALS = "usingDecimals";
	private static final String NUMBER_VALUE = "numberValue";
	
	private static final CompressedResourceReference LUNA_CSS = 
		new CompressedResourceReference(SliderScriptingBehavior.class, "res/css/luna/luna.css");
	private static final CompressedResourceReference SWING_CSS = 
		new CompressedResourceReference(SliderScriptingBehavior.class, "res/css/swing/swing.css");
	private static final CompressedResourceReference BLUECURVE_CSS = 
		new CompressedResourceReference(SliderScriptingBehavior.class, "res/css/bluecurve/bluecurve.css");
	
	private static final JavascriptResourceReference RANGE_JS = new JavascriptResourceReference(SliderScriptingBehavior.class, "res/js/range.js");
	private static final JavascriptResourceReference TIMER_JS = new JavascriptResourceReference(SliderScriptingBehavior.class, "res/js/timer.js");
	private static final JavascriptResourceReference SLIDER_JS = new JavascriptResourceReference(SliderScriptingBehavior.class, "res/js/slider.js");
	
	private Hashtable map = new Hashtable();
	
	private ServoyWicketSlider parent;

	public SliderScriptingBehavior(ServoyWicketSlider parent) {
		super();
		this.parent = parent;
	}

	/* (non-Javadoc)
	 * @see org.apache.wicket.behavior.AbstractBehavior#renderHead(org.apache.wicket.markup.html.IHeaderResponse)
	 */
	@Override
	public void renderHead(IHeaderResponse response) {
		super.renderHead(response);
		
		ResourceReference sheet = LUNA_CSS;
		if (Utils.stringSafeEquals(parent.getWebStyleType(), IServoySliderBean.SWING_STYLE)) {
			sheet = SWING_CSS;
		} else if (Utils.stringSafeEquals(parent.getWebStyleType(), IServoySliderBean.BLUECURVE_STYLE)) {
			sheet = BLUECURVE_CSS;
		}
	    response.renderCSSReference(sheet);
	    response.renderJavascriptReference(RANGE_JS);
	    response.renderJavascriptReference(TIMER_JS);
	    response.renderJavascriptReference(SLIDER_JS);
	    
	    final String ID = parent.getId();
	    final String markupID = parent.getMarkupId();
        final String orientation = (parent.getOrientation() == 0) ? "horizontal" : "vertical"; // the JavaScript object is using a String while the Swing bean uses int

	    StringBuffer css = new StringBuffer();
	    css.append(CssUtils.INLINE_OPEN_TAG);
	    css.append("#"+ID +"{\n");
	    css.append("vertical-align: top;\n");
	    css.append("\tfont: normal 11px Tahoma, Verdana, Arial, Sans-Serif;\n");
	    css.append("\toverflow: visible;\n");
	    css.append("}");
	    css.append(CssUtils.INLINE_CLOSE_TAG);
	    response.renderString(css.toString());
	    
	    final String varID = "g_" + ID;
	    response.renderJavascript("var "+varID+";", varID);
	    
	    StringBuffer buff = new StringBuffer();
        
    	buff.append("var sliderEl = document.getElementById ? document.getElementById('" + markupID + "') : null;\n");
    	buff.append("var backingEl = document.getElementById ? document.getElementById('slider-backing-" + ID + "') : null;\n");
     	buff.append("var s = new Slider(sliderEl, backingEl, '" + orientation + "');\n");
        map.put(ORIENTATION, orientation);
    	buff.append(varID+" = s;\n");
        
    	buff.append(insertPropertyScripts(true));

        buff.append(varID+".onchange = function() {\n");
        buff.append("\tvar inputEl = document.getElementById ? document.getElementById('slider-input-" + ID + "') : null;\n");
        buff.append("\tif(inputEl) {\n");
        buff.append("\t\tinputEl.value = this.getExternalValue();\n");
        buff.append("\t\tinputEl.onchange();\n");
        buff.append("\t};\n");
        buff.append("};\n");

	    response.renderOnDomReadyJavascript(buff.toString());
	    
	}

	/* (non-Javadoc)
	 * @see org.apache.wicket.behavior.AbstractBehavior#onRendered(org.apache.wicket.Component)
	 */
	@Override
	public void onRendered(Component component) {
		Response response = component.getResponse();
		
	    StringBuffer buff = insertPropertyScripts(false);
        if (buff.length() > 0) {
		    response.write(JavascriptUtils.SCRIPT_OPEN_TAG);
		    response.write(buff.toString());
	        response.write(JavascriptUtils.SCRIPT_CLOSE_TAG);
        }
        
		super.onRendered(component);
	}

	/**
	 * @param header true if first insert
	 * @return StringBuffer
	 */
	private StringBuffer insertPropertyScripts(boolean header) {
		Debug.error("insertPropertyScripts called");
		final String ID = parent.getId();
        final String orientation = (parent.getOrientation() == 0) ? "horizontal" : "vertical";
	    final String varID = "g_" + ID;
        
        StringBuffer buff = new StringBuffer();
        
        if (header || !Utils.stringSafeEquals(orientation, (String)map.get(ORIENTATION))) {
        	buff.append(varID+".setOrientation('" + orientation + "');\n");
        	map.put(ORIENTATION, orientation);
        }
        if (header || !Utils.stringSafeEquals(parent.getWebStyleType(), (String)map.get(STYLE_TYPE))) {
        	buff.append(varID+".setStyleType('" + parent.getWebStyleType() + "');\n");
        	map.put(STYLE_TYPE, parent.getWebStyleType());
        }
        
        if (header || !ServoyUtils.intEquals(parent.getMinimumValue(), (Integer)map.get(MINIMUM))) {
            buff.append(varID+".setMinimum("+parent.getMinimumValue()+");\n");
            map.put(MINIMUM, parent.getMinimumValue());
        }
        if (header || !ServoyUtils.intEquals(parent.getMaximumValue(), (Integer)map.get(MAXIMUM))) {
            buff.append(varID+".setMaximum("+parent.getMaximumValue()+");\n");
            map.put(MAXIMUM, parent.getMaximumValue());
        }
        if (header || !ServoyUtils.intEquals(parent.getMajorTicks(), (Integer)map.get(MAJOR_TICKS))) {
        	buff.append(varID+".setMajorTickSpacing("+parent.getMajorTicks()+");\n");
        	map.put(MAJOR_TICKS, parent.getMajorTicks());
        }
        if (header || !ServoyUtils.intEquals(parent.getMinorTicks(), (Integer)map.get(MINOR_TICKS))) {
        	buff.append(varID+".setMinorTickSpacing("+parent.getMinorTicks()+");\n");
        	buff.append(varID+".setBlockIncrement("+parent.getMinorTicks()+");\n");
        	map.put(MINOR_TICKS, parent.getMinorTicks());
        }
        
        if (header || !ServoyUtils.booleanEquals(parent.getInverted(), (Boolean)map.get(INVERTED))) {
        	buff.append(varID+".setInverted("+parent.getInverted()+");\n");
        	map.put(INVERTED, parent.getInverted());
        }
        if (header || !ServoyUtils.booleanEquals(parent.getPaintTicks(), (Boolean)map.get(PAINT_TICKS))) {
        	buff.append(varID+".setPaintTicks("+parent.getPaintTicks()+");\n");
        	map.put(PAINT_TICKS, parent.getPaintTicks());
        }
        if (header || !ServoyUtils.booleanEquals(parent.getPaintLabels(), (Boolean)map.get(PAINT_LABELS))) {
        	buff.append(varID+".setPaintLabels("+parent.getPaintLabels()+");\n");
        	map.put(PAINT_LABELS, parent.getPaintLabels());
        }
        if (header || !ServoyUtils.booleanEquals(parent.getPaintTrack(), (Boolean)map.get(PAINT_TRACK))) {
        	buff.append(varID+".setPaintTrack("+parent.getPaintTrack()+");\n");
        	map.put(PAINT_TRACK, parent.getPaintTrack());
        }
        if (header || !ServoyUtils.booleanEquals(parent.getSnapToTicks(), (Boolean)map.get(SNAP_TO_TICKS))) {
        	buff.append(varID+".setSnapToTicks("+parent.getSnapToTicks()+");\n");
        	map.put(SNAP_TO_TICKS, parent.getSnapToTicks());
        }
        
        if (header || !ServoyUtils.intEquals(parent.getPrecision(), (Integer)map.get(PRECISION))) {
	        buff.append(varID+".setPrecision("+parent.getPrecision()+");\n");
	        map.put(PRECISION, parent.getPrecision());
        }
        if (header || !ServoyUtils.booleanEquals(parent.isUsingDecimals(), (Boolean)map.get(USING_DECIMALS))) {
        	buff.append(varID+".setUsingDecimals("+parent.isUsingDecimals()+");\n");
        	map.put(USING_DECIMALS, parent.isUsingDecimals());
        }
        
        if (header || !ServoyUtils.doubleEquals(parent.getNumberValue(), (Double)map.get(NUMBER_VALUE))) {
        	buff.append(varID+".setExternalValue("+parent.getNumberValue()+");\n");
        	map.put(NUMBER_VALUE, parent.getNumberValue());
        }
        
        if (header || !ServoyUtils.booleanEquals(parent.isEnabled(), (Boolean)map.get(ENABLED))) {
        	buff.append(varID+".setEnabled("+parent.isEnabled()+");\n");
        	map.put(ENABLED, parent.isEnabled());
        }
		return buff;
	}

	
}
